<?php

namespace App\Utility;

use App\Utility\Pool\RedisDatasPool;
use EasySwoole\Component\Pool\PoolManager;
use EasySwoole\EasySwoole\Config;

class CacheDatas{

    protected $redis;
    protected $options;

    public function __construct(){
        $options = Config::getInstance()->getConf('redis2');
        $redis = PoolManager::getInstance()->getPool(RedisDatasPool::class)
            ->getObj($options['pool_time_out']);
        if ($redis) {
            $this->redis = $redis;
            $this->options = $options;
        } else {
            //直接抛给异常处理，不往下
            throw new \Exception('error,Redis Pool is Empty');
        }
    }

    public function __destruct(){
        PoolManager::getInstance()->getPool(RedisDatasPool::class)->recycleObj($this->redis);
    }

    //序列化数据
    protected function packData($data){
        return serialize($data);
    }

    //反序列化数据
    protected function unPackData($data){
        return unserialize($data);
    }

    //获取指定 key 的值。
    public function get($name, $default = null){
        $key   = $this->getCacheKey($name);
        $value = $this->redis->get($key);
        if (is_null($value) || false === $value) {
            return $default;
        }
        return is_numeric($value) ? $value : $this->unPackData($value);
    }

    //设置指定 key 的值
    public function set($name, $value, $expire = null){
        if (is_null($expire)) {
            $expire = $this->options['expire'];
        }
        $key   = $this->getCacheKey($name);
        $expire= $this->getExpireTime($expire);
        $value = is_numeric($value) ? $value : $this->packData($value);
        if ($expire) {
            $result = $this->redis->setex($key, $expire, $value);
        } else {
            $result = $this->redis->set($key, $value);
        }
        return $result;
    }


    //设置 key 的过期时间，key 过期后将不再可用。单位以秒计。
    public function expire($key, $integer){
        return $this->redis->expire($key, $integer);
    }

    //检查给定 key 是否存在
    public function has($name){
        return $this->redis->exists($this->getCacheKey($name));
    }

    //获取缓存前缀
    protected function getCacheKey($name){
        return $this->options['prefix'].$name;
    }

    //过期时间
    protected function getExpireTime($expire){
        if ($expire instanceof \DateTime) {
            $expire = $expire->getTimestamp() - time();
        }
        return (int) $expire;
    }


    //向无序集合中批量增加元素
    public function sAddBatch($key,$value,$expire=0){
        if(is_array($value)){
            array_walk($value,function (&$item){
                $item = $this->packData($item);
            });
            array_unshift($value,$key);
            $result = call_user_func_array(array($this->redis, "sAdd"),$value);
        }else{
            $result = $this->redis->sAdd($key, $this->packData($value));
        }
        if((int)$expire > 0) $this->expire($key,$expire);
        return $result;
    }


    //返回无序集合中的一个或多个随机元素
    public function sRandBatch($key, $count=null){
        $data = $this->redis->sRandMember($key,$count);
        if(is_array($data)){
            array_walk($data,function (&$item){
                $item = $this->unPackData($item);
            });
        }else{
            $data = $this->unPackData($data);
        }
        return $data;
    }







}
